﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Net.Sockets;
using System.Net;
using System.Windows.Forms;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace collabr8
{
    public partial class ViewerForm : Form
    {
        private TcpClient tcpClient;
        private VideoCodec decoder;
        private Frame currentFrame;
        private Bitmap decodedFrame;
        private BinaryFormatter formatter;
        private bool Connected = false;
        private ClientForm father;
        private int x, y;
        private SolidBrush brush;

        public ViewerForm()
        {
            InitializeComponent();
        }

        public ViewerForm(ClientForm father, IPAddress ip, int port, int width, int height)
        {
            InitializeComponent();
            this.father = father;
            this.Location = father.Location;
            this.Top += 400;
            this.Width = width;
            this.Height = height;
            this.brush = new SolidBrush(Color.FromArgb(128, 204, 0, 0));

            // Start a new TCP connections to the video server
            this.tcpClient = new TcpClient();
            this.tcpClient.Connect(ip, port);

            // Helps us track whether we're connected or not
            this.Connected = true;

            // Create the formatter, used to deserialize frames:
            this.formatter = new BinaryFormatter();
            this.decoder = new VideoCodec();
        }

        public void ReceiveVideo()
        {
            try
            {
                while (Connected)
                {
                    if (this.currentFrame != null)
                        this.currentFrame.Dispose();
                    /*if (this.decodedFrame != null)
                        this.decodedFrame.Dispose();   // See: VideoCodec.Decode */
                    this.currentFrame = (Frame)this.formatter.Deserialize(tcpClient.GetStream());
                    this.x = currentFrame.MouseX;
                    this.y = currentFrame.MouseY;
                    this.decodedFrame = this.decoder.Decode(this.currentFrame);
                    father.Invoke(father.refreshDelegate);
                }
            }
            catch
            {
                this.Connected = false;
                tcpClient.Close();
                father.Invoke(father.closeDelegate);
            }   
        }

        private void ViewerForm_Paint(object sender, PaintEventArgs e)
        {
            if (this.decodedFrame != null)
            {
                this.Width = decodedFrame.Width;
                this.Height = decodedFrame.Height;

                e.Graphics.DrawImage(this.decodedFrame, new Point(0, 0));

                if (this.x != 0 && this.y != 0)
                {
                    e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                    e.Graphics.FillEllipse(this.brush, this.x-17, this.y-17, 34, 34); 
                }
            }  
            /*
            if (this.currentFrame != null)    // Use to show off VideoCodec's effectiveness!
            {
                e.Graphics.DrawImage(this.currentFrame.Bitmap, new Point(0, 0));
            } 
            */ 
        }

        private void ViewerForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.Connected = false;
            tcpClient.Close();
        }

    }
}
